package com.itheima.tliasmanagement.aop;

import com.alibaba.fastjson2.JSON;
import com.itheima.tliasmanagement.entity.OperateLog;
import com.itheima.tliasmanagement.mapper.OperateLogMapper;
import com.itheima.tliasmanagement.util.UserThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

@Slf4j
@Aspect
@Component
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper logMapper;


    @Around("@annotation(mylog)")
    public Object around(ProceedingJoinPoint pjp, MyLog mylog) throws Throwable {
        log.info(" LogAspect around");
        // 操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值、方法执行时长
        // 先拿到request
//        // 从request中获取到token
//        String token = request.getHeader("token");
//        // 解析token中的userId
//        Claims claims = JwtUtils.parseJWT(token);
//        Integer id = claims.get("id", Integer.class);
//        String username = claims.get("username", String.class);
        // 从当前线程中获取用户信息
        UserThreadLocal.UserInfo userInfo = UserThreadLocal.getUserInfo();
        Integer id = userInfo.getId();
        String username = userInfo.getName();
        // 从pjp中获取类名、执行方法名、方法运行时参数、返回值
        Signature signature = pjp.getSignature();
        String methodName = signature.getName();
        String className = signature.getDeclaringTypeName();
        Object[] args = pjp.getArgs();
        long start = System.currentTimeMillis();
        Object result = null;
        long costTime = 0;
        try{
            // 执行业务逻辑
            result = pjp.proceed();
            long end =  System.currentTimeMillis();
            costTime = (end - start);
        }finally{
            OperateLog log = OperateLog.builder()
                    .operateUser(id)
                    .operateName(username)
                    .className(className)
                    .methodName(methodName)
                    .methodParams(args==null?"": JSON.toJSONString(args))
                    .returnValue(result==null?"":JSON.toJSONString(result))
                    .costTime(costTime)
                    .methodDesc(mylog.desc())
                    .operateTime(LocalDateTime.now())
                    .build();
            // 插入log
            logMapper.insertOperateLog(log);
        }
        return result;
    }

}
